var sanitize = require('validator').sanitize;

var Tag = require('../proxy').Tag;
var List = require('../proxy').List;
var User = require('../proxy').User;

var config = require('../config').config;
var EventProxy = require('eventproxy');

var ArrayHelper = require('../libs/arrayhelper');

/**
 * home page of list
 * @param  {[type]}   req  [description]
 * @param  {[type]}   res  [description]
 * @param  {Function} next [description]
 * @return {[type]}        [description]
 */
exports.index = function (req, res, next) {
  var user_name = req.params.username;
  var own_page = (user_name == req.session.user.name);
  User.getUserByName(user_name, function(err, user) {
    if (err) return next(err);
    List.getListsByUserId(user._id, function(err, lists) {
      if (err) return next(err);
      // TODO: 考虑把标签放入session里面
      Tag.getAllTags(function (err, tags) {
        res.render('list/index', {lists: lists, tags: tags, own_page: own_page});
      });
    });
  });
};

exports.new = function (req, res, next) {
  Tag.getAllTags(function (err, tags) {
    if (err) return next(err);
    res.partial('list/new', {tags: tags});
  });
};

exports.add = function (req, res, next) {
  var name = sanitize(req.body.name).trim();
  name = sanitize(name).xss();
  var desc = sanitize(req.body.desc).trim();
  desc = sanitize(desc).xss();
  var tag_id = req.body.tag;
  var user = req.session.user;

  if (name === '') {
    res.render('notify/notify', {error: '信息不完整。'});
    return;
  }

  var ep = new EventProxy();
  var done = function (unique, tag, user, count) {
    List.newAndSave(name, desc, count, user._id, tag._id, ep.done(function() {
      res.redirect('/' + user.name + '/lists');
    }));
  };
  ep.assign('unique_check', 'tag_updated', 'user_updated', 'get_list_count', done);
  ep.fail(next);
  List.getListByNameAndUserId(name, req.session.user._id, ep.done(function (list) {
    if (list) return res.render('notify/notify', {error: '分类已存在！'});
    ep.emit('unique_check');

    Tag.getTagById(tag_id, ep.done(function (tag) {
      if (!tag) return res.render('notify/notify', {error: '标签不存在。'});
      tag.list_count += 1;
      tag.save(ep.done('tag_updated'));
    }));
    User.getUserById(user._id, ep.done(function (user) {
      if (!user) return res.render('notify/notify', {error: '数据异常。'});
      user.list_count += 1;
      user.save(ep.done('user_updated'));
    }));
    List.getCount(ep.done('get_list_count'));
  }));
};

exports.edit = function (req, res, next) {
  var name = req.params.name;
  List.getListByNameAndUserId(name, req.session.user._id, function (err, list) {
    if (err) return next(err);
    if (!list) return res.render('notify/notify', {error: '没有这个分类。'});

    Tag.getAllTags(function (err, tags) {
      if (err) return next(err);
      res.partial('list/edit', {list: list, tags: tags});
    });
  });
};

exports.follow = function (req, res, next) {
  var id = req.params.id;
  var user_id = req.session.user._id;

  List.getListById(id, function (err, list) {
    if (err) return next(err);
    if (!list) return res.render('notify/notify', {error: '分类不存在。'});
    if (list && list.user_id == user_id) {
      return res.render('notify/notify', {error: '不能关注自己的分类。'});
    }

    var ep = new EventProxy();
    var ready = function (owner, follower) {
      // 分别更新两个用户的followers和followings
      var done = function () {
        res.redirect('back');
      };
      ep.assign('owner_updated', 'follower_updated', 'list_updated', done);

      ArrayHelper.uniquePush(owner.followers, follower._id);
      owner.follower_count = owner.followers.length;

      if (follower.followings[owner._id]) {
        ArrayHelper.uniquePush(follower.followings[owner._id], list._id);
      } else {
        follower.followings[owner._id] = [list._id];
        follower.following_count += 1;
      }

      ArrayHelper.uniquePush(list.followers, follower._id);
      list.follower_count = list.followers.length;

      owner.save(ep.done('owner_updated'));
      follower.save(ep.done('follower_updated'));
      list.save(ep.done('list_updated'));
    };
    ep.assign('get_owner', 'get_follower', ready);
    ep.fail(next);

    User.getUserById(list.user_id, ep.done('get_owner'));
    User.getUserById(user_id, ep.done('get_follower'));
  });
};

exports.unfollow = function (req, res, next) {
  var id = req.params.id;
  var user_id = req.session.user._id;

  List.getListById(id, function (err, list) {
    if (err) return next(err);
    if (!list) return res.render('notify/notify', {error: '没有这个分类。'});

    var ep = new EventProxy();
    var ready = function (owner, follower) {
      var done = function () {
        res.redirect('back');
      };
      ep.assign('owner_updated', 'follower_updated', 'list_updated', done);

      if (follower.followings[owner._id]) {
        ArrayHelper.remove(follower.followings[owner._id], list._id);
        if (!follower.followings[owner._id].length) {
          delete follower.followings[owner._id];
          follower.following_count -= 1;

          ArrayHelper.remove(owner.followers, follower._id);
          owner.follower_count = owner.followers.length;
        }
        ArrayHelper.remove(list.followers, follower._id);
        list.follower_count = list.followers.length;

        owner.save(ep.done('owner_updated'));
        follower.save(ep.done('follower_updated'));
        list.save(ep.done('list_updated'));
      }
    };
    ep.assign('get_owner', 'get_follower', ready);
    ep.fail(next);

    User.getUserById(list.user_id, ep.done('get_owner'));
    User.getUserById(user_id, ep.done('get_follower'));
  })
};

exports.follow2 = function (req, res, next) {
  var id = req.params.id;
  var user_id = req.session.user._id;

  List.getListById(id, function (err, list) {
    if (err) return next(err);
    if (!list) return res.render('notify/notify', {error: '分类不存在。'});
    if (list && list.user_id == user_id) {
      return res.render('notify/notify', {error: '不能关注自己的分类。'});
    }

    var has = false;
    list.followers.forEach(function (uid) {
      if (user_id == uid) has = true;
    });
    if (has) {
      res.redirect('back');
    } else {
      list.followers.push(user_id);
      list.follower_count += 1;
      list.save(function (err) {
        if (err) return next(err);
        res.redirect('back');
      });
    }
  });
};

exports.unfollow2 = function (req, res, next) {
  var id = req.params.id;
  var user_id = req.session.user._id;

  List.getListById(id, function (err, list) {
    if (err) return next(err);
    if (!list) return res.render('notify/notify', {error: '没有这个分类。'});

    for (var i = 0, n = list.followers.length; i < n; i++) {
      if (list.followers[i] == user_id) {
        list.followers.splice(i, 1);
        list.follower_count = n - 1;
        break;
      }
    }
    list.save(function (err) {
      if (err) return next(err);
      res.redirect('back');
    });
  })
};

exports.update = function (req, res, next) {
  var id = req.params.id;
  List.getListById(id, function (err, list) {
    if (err) return next(err);
    if (!list) return res.render('notify/notify', {error: '没有这个分类。'});

    var name = sanitize(req.body.name).trim();
    name = sanitize(name).xss();
    var desc = sanitize(req.body.desc).trim();
    desc = sanitize(desc).xss();
    var tag_id = req.body.tag;
    if (name === '') {
      res.render('notify/notify', {error: '信息不完整。'});
      return;
    }
    var ep = new EventProxy();
    var done = function () {
      list.name = name;
      list.desc = desc;
      list.tag_id = tag_id;
      list.save(ep.done(function () {
        res.redirect('/' + req.session.user.name + '/lists');
      }));
    };
    ep.assign('unique_check', 'old_tag_updated', 'new_tag_updated', done);
    ep.fail(next);
    List.getListByNameAndUserId(name, req.session.user._id, ep.done(function (has) {
      if (list.name != name && has) return res.render('notify/notify', {error: '分类已存在！'});
      ep.emit('unique_check');

      if (list.tag_id == tag_id) {
        ep.emit('old_tag_updated');
        ep.emit('new_tag_updated');
      } else {
        Tag.getTagById(list.tag_id, ep.done(function (oldTag) {
          if (!oldTag) return res.render('notify/notify', {error: '标签异常。'});
          oldTag.list_count -= 1;
          oldTag.save(ep.done('old_tag_updated'));
        }));
        Tag.getTagById(tag_id, ep.done(function (newTag) {
          if (!newTag) return res.render('notify/notify', {error: '标签异常。'});
          newTag.list_count += 1;
          newTag.save(ep.done('new_tag_updated'));
        }));
      }
    }));
  });
};

exports.delete = function (req, res, next) {
  var name = req.params.name;
  List.getListByNameAndUserId(name, req.session.user._id, function (err, list) {
    if (err) return next(err);
    if (!list) return res.render('notify/notify', {error: '没有这个分类。'});

    var ep = new EventProxy();
    var list_count_deleted = function () {
      var done = function () {
        list.remove(ep.done(function () {
          res.redirect('/' + req.session.user.name + '/lists');
        }));
      };
      ep.after('follower_updated', list.follower_count, done);

      list.followers.forEach(function (uid) {
        User.getUserById(uid, ep.done(function (user) {
          if (!user) return res.render('notify/notify', {error: '数据异常。'});
          ArrayHelper.remove(user.followings[list.user_id], list._id);
          user.save(ep.done('follower_updated'));
        }));
      });
    };

    ep.assign('tag_count_deleted', 'user_count_deleted', list_count_deleted);
    ep.fail(next);

    Tag.getTagById(list.tag_id, ep.done(function (tag) {
      if (!tag) return res.render('notify/notify', {error: '标签异常。'});
      tag.list_count -= 1;
      tag.save(ep.done('tag_count_deleted'));
    }));
    User.getUserById(list._id, ep.done(function (user) {
      if (!user) return res.render('notify/notify', {error: '数据异常。'});
      user.list_count -= 1;
      user.save(ep.done('user_count_deleted'));
    }))
  });
};
